﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace CmdLine
{
    public abstract class ArgumentsParser : IArguments
    {
        private string OPTION_PATTERN = "--(.*?)=(.*)";

        protected ArgumentsParser(String[] args)
        {
            Arguments = new List<String>();
            Options = new Dictionary<String, String>();
            foreach (String arg in args)
            {
                Match m = Regex.Match(arg, OPTION_PATTERN);
                if (m.Success)
                {
                    Options.Add(m.Groups[1].Value, m.Groups[2].Value);
                }
                else
                {
                    Arguments.Add(arg);
                }
            }
        }

        protected bool MinArgs(int count)
        {
            return MinArgs(count, Usage);
        }

        protected bool MinArgs(int count, string error)
        {
            if (Arguments.Count < count)
            {
                Console.WriteLine(error);
                return false;
            }
            return true;
        }

        protected bool MaxArgs(int count)
        {
            return MaxArgs(count, Usage);
        }

        protected bool MaxArgs(int count, string error)
        {
            if (Arguments.Count > count)
            {
                Console.WriteLine(error);
                return false;
            }
            return true;
        }

        protected bool Require(string option)
        {
            return Require(option, Usage);
        }

        protected bool Require(string option, string error)
        {
            if (!Options.ContainsKey(option))
            {
                Console.WriteLine(error);
                return false;
            }
            return true;
        }

        protected bool Depends(string option, string dependency)
        {
            return Depends(option, dependency, Usage);
        }

        protected bool Depends(string option, string dependency, string error)
        {
            if (Options.ContainsKey(option) && !Options.ContainsKey(dependency)) {
                Console.WriteLine(error);
                return false;
            }
            return true;
        }

        public abstract string Usage { get; }
        public abstract bool Valid();

        public IList<string> Arguments
        {
            get;
            private set;
        }

        public IDictionary<string, string> Options
        {
            get;
            private set;
        }
    }
}
